//
//  PPAbstractTimelineViewController.m
//  pickpic
//
//  Created by Jinxiao on 8/27/16.
//  Copyright © 2016 MicroDream. All rights reserved.
//

#import "PPAbstractTimelineViewController.h"

@interface PPAbstractTimelineViewController () <DGScrollViewWrapperDelegate, UITableViewDelegate, UITableViewDataSource>
@property (readwrite, nonatomic, strong) UITableView *tableView;
@property (readwrite, nonatomic, strong) DGScrollViewWrapper *scrollWrapper;
@property (readwrite, nonatomic, strong) NSMutableArray *items;
@property (readwrite, nonatomic, strong) UIActivityIndicatorView *loadNewIndicatorView;
@property (readwrite, nonatomic, strong) UIActivityIndicatorView *loadMoreIndicatorView;
@property (readwrite, nonatomic, strong) UIView *emptyPromptView;
@end

@implementation PPAbstractTimelineViewController

- (void)dealloc {
    _tableView.delegate = nil;

    _scrollWrapper.scrollView.delegate = nil;
    _scrollWrapper.delegate = nil;
    _scrollWrapper = nil;
}

- (void)viewDidLoad {
    [super viewDidLoad];

    _tableView = [[UITableView alloc] initWithFrame:self.view.bounds style:[self preferredTableViewStyle]];
    _tableView.showsVerticalScrollIndicator = NO;
    _tableView.showsHorizontalScrollIndicator = NO;
    [self.view addSubview:_tableView];

    UIView *footerView = [[UIView alloc] init];
    footerView.backgroundColor = [UIColor clearColor];
    footerView.frame = CGRectMake(0, 0, CGFLOAT_MIN, CGFLOAT_MIN);
    _tableView.tableFooterView = footerView;

    _scrollWrapper = [[DGScrollViewWrapper alloc] initWithScrollView:_tableView];
    _scrollWrapper.originalInset = [self preferredScrollInsets];
    _scrollWrapper.enableLoadNew = YES;
    _scrollWrapper.enableLoadMore = YES;
    _scrollWrapper.delegate = self;
    [_scrollWrapper initialize];

    _tableView.delegate = self;
    _tableView.dataSource = self;

    [_tableView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.edges.equalTo(self.view);
    }];

    _items = [[NSMutableArray alloc] init];

    [_items addObjectsFromArray:[self initialItems]];
    
    if([self prefersRefreshAutomatically]) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [_scrollWrapper triggerLoadNew];
        });
    }
}

- (void)setEmptyPromptView:(UIView *)emptyPromptView {
    if(_emptyPromptView == emptyPromptView) {
        return;
    }

    if(_emptyPromptView != nil) {
        [_emptyPromptView removeFromSuperview];
        _emptyPromptView = nil;
    }

    if(emptyPromptView != nil) {
        _emptyPromptView = emptyPromptView;

        [_tableView addSubview:_emptyPromptView];

        [_emptyPromptView mas_makeConstraints:^(MASConstraintMaker *make) {
            CGPoint center = [self preferredEmptyPromptViewCenter];
            make.centerX.equalTo(_tableView.mas_leading).offset(center.x);
            make.centerY.equalTo(_tableView.mas_top).offset(center.y);
        }];
    }
}

- (NSArray *)initialItems {
    return nil;
}

- (void)cacheItems:(NSArray *)items {

}

- (void)fetchNewItems {
    [_loadNewIndicatorView startAnimating];
}

- (void)fetchMoreItems {
    [_loadMoreIndicatorView startAnimating];
}

- (void)clearItems {

}

- (void)removeItem:(id)item {
    [_items removeObject:item];

    [self cacheItems:_items];
}

- (void)removeAllItems {
    [_items removeAllObjects];

    [self cacheItems:_items];
}

- (NSArray *)didReceiveNewResult:(id)result {
    [_loadNewIndicatorView stopAnimating];

    [_scrollWrapper finishLoading];

    NSArray *items = nil;
    NSError *error = nil;

    if([result isKindOfClass:[NSError class]]) {
        error = result;
    } else {
        [self clearItems];
        
        items = [self itemsFromResult:result];

        [self processNewItems:items];

        [_tableView reloadData];
    }

    if(_items.count == 0) {
        UIView *emptyPromptView = [self emptyPromptViewForError:error];
        self.emptyPromptView = emptyPromptView;
    } else {
        self.emptyPromptView = nil;
    }

    return items;
}

- (NSArray *)didReceiveMoreResult:(id)result {
    [_loadMoreIndicatorView stopAnimating];

    [_scrollWrapper finishLoading];

    if([result isKindOfClass:[NSError class]]) {
        return nil;
    } else {
        NSArray *moreItems = [self itemsFromResult:result];

        if(moreItems.count > 0) {
            [self processMoreItems:moreItems];

            [_tableView reloadData];
        } else {
            // TODO: disable load more
        }

        return moreItems;
    }
}

- (void)processNewItems:(NSArray *)newItems {
    [_items removeAllObjects];
    [_items addObjectsFromArray:newItems];

    [self cacheItems:_items];

    [_tableView reloadData];
}

- (void)processMoreItems:(NSArray *)moreItems {
    [_items addObjectsFromArray:moreItems];

    [self cacheItems:_items];
}

- (NSArray *)itemsFromResult:(id)result {
    return nil;
}

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return _items.count;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    return [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
}

// MARK: UIScrollViewDelegate

- (void)scrollViewDidScroll:(UIScrollView *)scrollView {
    [_scrollWrapper scrollViewDidScroll:scrollView];
}

- (void)scrollViewWillBeginDecelerating:(UIScrollView *)scrollView {
    [_scrollWrapper scrollViewDidEndDragging:scrollView];
}

// MARK: DGScrollWrapperDelegate

- (void)scrollViewWrapperDidTriggerLoadNew:(DGScrollViewWrapper *)scrollViewWrapper {
    [self fetchNewItems];
}

- (void)scrollViewWrapperDidTriggerLoadMore:(DGScrollViewWrapper *)scrollViewWrapper {
    [self fetchMoreItems];
}

- (void)scrollViewWrapper:(DGScrollViewWrapper *)scrollViewWrapper animatedWithStatus:(DGScrollViewStatus)status action:(DGScrollViewAction)action actionView:(UIView *)actionView progress:(float)progress {
    if(action == DGScrollViewActionLoadNew) {
        if(_loadNewIndicatorView == nil) {
            UIActivityIndicatorView *indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
            indicatorView.frame = CGRectMake((actionView.width - 20)/2, actionView.height - kLoadNewHeaderHeight + (kLoadNewHeaderHeight - 20)/2, 20, 20);
            indicatorView.tag = 1002;
            indicatorView.hidesWhenStopped = NO;
            [actionView addSubview:indicatorView];

            _loadNewIndicatorView = indicatorView;
        }

        if(!_loadNewIndicatorView.isAnimating) {
            _loadNewIndicatorView.transform = CGAffineTransformMakeRotation(progress*M_PI);
        } else {
            _loadNewIndicatorView.transform = CGAffineTransformIdentity;
        }
    } else if(action == DGScrollViewActionLoadMore) {
        if(_loadMoreIndicatorView == nil) {
            UIActivityIndicatorView *indicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
            indicatorView.frame = CGRectMake((actionView.width - 20)/2, actionView.height - kLoadNewHeaderHeight + (kLoadNewHeaderHeight - 20)/2, 20, 20);
            indicatorView.tag = 1002;
            indicatorView.hidesWhenStopped = NO;
            [actionView addSubview:indicatorView];

            _loadMoreIndicatorView = indicatorView;
        }

        if(!_loadMoreIndicatorView.isAnimating) {
            _loadMoreIndicatorView.transform = CGAffineTransformMakeRotation(progress*M_PI);
        } else {
            _loadMoreIndicatorView.transform = CGAffineTransformIdentity;
        }
    }
}

- (UITableViewStyle)preferredTableViewStyle {
    return UITableViewStylePlain;
}

- (UIEdgeInsets)preferredScrollInsets {
    return UIEdgeInsetsMake(0, 0, 0, 0);
}

- (UIView *)emptyPromptViewForError:(NSError *)error {
    return nil;
}

- (CGPoint)preferredEmptyPromptViewCenter {
    return CGPointMake(_tableView.width/2, _tableView.height*0.336);
}

- (void)reloadDataSource {
    [_items removeAllObjects];
    [_items addObjectsFromArray:[self initialItems]];

    if(_items.count == 0) {
        UIView *emptyPromptView = [self emptyPromptViewForError:nil];
        self.emptyPromptView = emptyPromptView;
    } else {
        self.emptyPromptView = nil;
    }
    [self.tableView reloadData];
}

- (BOOL)prefersRefreshAutomatically {
    return YES;
}

@end
